class CardFactory {
	private static _ins:CardFactory
	public static get instance(){
		if(!CardFactory._ins){
			CardFactory._ins = new CardFactory()
		}
		return CardFactory._ins
	}
	private _weaponData:ICardData[]
	private _setShieldData:ICardData[]
	private _actShieldData:ICardData[]
	private _skillData:ICardData[]
	/**全卡池 */
	private _cardPool:ICardData[]
	public constructor() {
		const t = this
		t._weaponData = RES.getRes('weaponcards_json')
		t._setShieldData = RES.getRes('setsheldcards_json')
		t._actShieldData = RES.getRes('actsheldcards_json')
		t._skillData = RES.getRes('skillcards_json')
		t._cardPool = [...t._weaponData, ...t._setShieldData, ...t._actShieldData, ...t._skillData]
	}

	public rawData2Card(data:ICardData){
		switch(data.cty){
			case CardType.WEAPON:
				return new WeaponCard(data)
			case CardType.SET_SHIELD:
				return new SetShieldCard(data)
			case CardType.ACT_SHIELD:
				return new ActShieldCard(data)
			case CardType.SKILL:
				return new SkillCard(data)
		}
	}

	public get1RandomCard(rare:RareType|-1=-1){
		const tmp = Math.floor(Math.random()*4)
		switch(tmp){
			case CardType.WEAPON:
				return this.getRandomWeapon(-1, rare)
			case CardType.SET_SHIELD:
				return this.getRandomShield('set', -1, rare)
			case CardType.ACT_SHIELD:
				return this.getRandomShield('act', -1, rare)
			case CardType.SKILL:
				return this.getRandomSkill(rare)
		}
	}

	public getNRandomCard(n:number = 1, rare:RareType|-1=-1, repeatable:boolean=false):ICardData[]{
		const t = this
		let arr:ICardData[] = t._cardPool
		if(rare!=-1){
			arr = arr.filter((v,i)=>{
				return v.rare == rare
			})
		}
		return t.randomNFromArr(arr, n, repeatable)
	}

	public getRandomCardExceptWeapon(n:number = 1, rare:RareType|-1=-1, repeatable:boolean=false):ICardData[]{
		const t = this
		let arr:ICardData[] = t._cardPool.slice(t._weaponData.length)
		if(rare!=-1){
			arr = arr.filter((v,i)=>{
				return v.rare == rare
			})
		}
		return t.randomNFromArr(arr, n, repeatable)
	}

	public getRandomWeapon(ty:WeaponType|-1=-1, rare:RareType|-1=-1, n:number=1){
		let arr = this._weaponData
		if(rare!=-1){
			arr = arr.filter((value, index)=>{
				return value.rare == rare
			})
		}
		if(ty!=-1){
			arr = arr.filter((value, index)=>{
				return value.wp.ty == ty
			})
		}
		return this.randomNFromArr(arr, n, false)
	}

	public getRandomShield(ty:"act"|"set", defty:WeaponType|-1=-1 ,rare:RareType|-1=-1, n:number=1){
		let arr = ty=='act'?this._actShieldData:this._setShieldData
		if(rare!=-1){
			arr = arr.filter((value, index)=>{
				return value.rare == rare
			})
		}
		if(defty!=-1){
			arr = arr.filter((value, index)=>{
				return value.dp.indexOf(defty) >= 0
			})
		}
		return this.randomNFromArr(arr, n, false)
	}

	public getRandomSkill(rare:RareType|-1=-1, repeatable:boolean=false, n:number=1){
		let arr = this._skillData
		if(rare!=-1){
			arr = arr.filter((value, index)=>{
				return value.rare == rare
			})
		}
		return this.randomNFromArr(arr, n, repeatable)
	}


	private randomNFromArr<T>(arr:T[], n:number, reapeatable:boolean=false):T[]{
		let idxs:number[] = []
		for(let i=0;i<arr.length;i++) idxs.push(i)
		let ret:T[] = []
		// console.log(`--------------随机${n}张卡-------------`)
		while(ret.length < n && idxs.length > 0){
			const tmp = Math.floor(Math.random()*idxs.length)
			const cd = arr[idxs[tmp]]
			// console.log(cd)
			ret.push(cd)
			if(!reapeatable){
				idxs.splice(tmp,1)
			}
		}
		// console.log('-----------------------------------')
		return ret
	}

	/**卡池大小 */
	public get cardPoolSize(){
		return this._cardPool.length
	}
}